package cn.rokhdelar.umbrsapi.config;

import cn.rokhdelar.umbrsapi.management.entity.SysUser;
import cn.rokhdelar.umbrsapi.management.repository.SysUserRepo;
import cn.rokhdelar.umbrsapi.management.service.JwtService;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    private final JwtService jwtService;
    private final SysUserRepo sysUserRepo;

    public JwtAuthenticationFilter(JwtService jwtService, SysUserRepo sysUserRepo) {
        this.jwtService = jwtService;
        this.sysUserRepo = sysUserRepo;
    }

    @Override
    protected void doFilterInternal(@NotNull HttpServletRequest request,
                                    @NotNull HttpServletResponse response,
                                    @NotNull FilterChain filterChain)
            throws ServletException, IOException {

        // 从 HTTP 请求中获取 Authorization header
        String authHeader = request.getHeader("Authorization");

        // 检查是否存在有效的授权头部（包含 'Bearer'）
        if (StringUtils.isEmpty(authHeader) || !StringUtils.startsWith(authHeader, "Bearer ")) {
            // 没有找到合法的授权头部，直接执行后续过滤器链
            filterChain.doFilter(request, response);
            return;
        }

        // 提取 JWT Token
        String jwtToken = authHeader.substring(7);

        // 初始化用户名为空
        String username;

        try {
            // 使用 JwtService 解码 JWT Token 获取用户名
            username = jwtService.getUsername(jwtToken);

        } catch (Exception e) {
            // 如果出现任何错误，返回未经授权的状态码
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return;
        }

        // 如果没有从 JWT 中解析出用户名，返回未经授权的状态码
        if (username == null) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return;
        }

        // 验证 Spring Security 上下文中是否已经存在认证对象
        if (StringUtils.isNotEmpty(username) && SecurityContextHolder.getContext().getAuthentication() == null) {

            // 查询数据库以根据用户名查找对应的 SysUser 对象
            SysUser user = sysUserRepo.findByUsername(username);

            Boolean tokenValid;
            try {
                // 使用 JwtService 验证 JWT Token 是否仍然有效
                tokenValid = jwtService.isTokenValid(jwtToken, user);
            } catch (Exception e) {
                // 如果出现任何错误，返回未经授权的状态码
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                return;
            }

            // 如果 JWT Token 有效且不存在已有的 Authentication 对象，创建新的 UsernamePasswordAuthenticationToken
            if (tokenValid) {
                SecurityContext context = SecurityContextHolder.createEmptyContext();
                UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
                        user, null, user.getAuthorities());

                // 为新创建的 Authentication 对象添加详细信息
                token.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

                // 将新建的 Authentication 对象设置为 Spring Security 上下文
                context.setAuthentication(token);
                SecurityContextHolder.setContext(context);
            }
        }

        // 执行后续过滤器链
        filterChain.doFilter(request, response);
    }

}
